import { shallowReactive, ref, Ref } from 'vue';
import { IPSDEListDataItem, IPSLayoutPanel, IPSUIAction, IPSUIActionGroupDetail } from '@ibiz/dynamic-model-api';
import { IMobMDCtrlController, MobMDCtrlController, ModelTool, Util, ViewTool } from 'ibz-core';
import { AppMobMDCtrlProps } from 'ibz-core';
import { GenerateComponent } from '../component-base';
import { MDCtrlComponentBase } from './md-ctrl-component-base';

export class AppMobMDCtrl extends MDCtrlComponentBase<AppMobMDCtrlProps> {
  /**
   * @description 多数据部件控制器
   * @protected
   * @type {IMobMDCtrlController}
   * @memberof AppMobMDCtrl
   */
  protected c!: IMobMDCtrlController;

  /**
   * @description 加载更多禁用状态
   * @type {boolean}
   * @memberof AppMobMDCtrl
   */
  public loadMoreDisabled: Ref<boolean> = ref(false);

  /**
   * @description 设置响应式
   * @memberof AppMobMDCtrl
   */
  setup() {
    this.c = shallowReactive<MobMDCtrlController>(this.getCtrlControllerByType('MOBMDCTRL') as MobMDCtrlController);
    super.setup();
  }

  /**
   * @description 初始化响应式属性
   * @memberof AppMobMDCtrl
   */
  public initReactive() {
    super.initReactive();
  }

  /**
   * @description 初始化数据ref引用
   * @param {any[]} items 数据
   * @memberof AppMobMDCtrl
   */
  public initItemRef(items: any[]) {
    items.forEach((item: any) => {
      this.refsMap.set(item.srfkey, ref(null));
    });
  }

  /**
   * @description 拖动
   * @memberof AppMobMDCtrl
   */
  public ionDrag() {
    // this.$store.commit('setPopupStatus', false)
  }

  /**
   * @description 加载更多
   * @param {*} event 事件源
   * @memberof AppMobMDCtrl
   */
  public loadMore(event: any) {
    if (this.c.needLoadMore) {
      if (this.c.loadBottom && this.c.loadBottom instanceof Function) {
        this.c
          .loadBottom()
          .then((response: any) => {
            event.target.complete();
          })
          .catch((error: any) => {
            event.target.complete();
          });
      }
    } else {
      this.loadMoreDisabled.value = true;
    }
  }

  /**
   * @description 单选值改变
   * @param {*} $event 数据源
   * @return {*}
   * @memberof AppMobMDCtrl
   */
  public simpleChange($event: any) {
    const { detail } = $event;
    if (!detail) {
      return;
    }
    const { value } = detail;
    const selections: any[] = [];
    const selectItem = this.c.items.find((item: any) => {
      return Object.is(item.srfkey, value);
    });
    selections.push(selectItem);
    this.c.selectionChange(selections);
  }

  /**
   * @description 多选值改变
   * @param {*} $event 数据源
   * @return {*}
   * @memberof AppMobMDCtrl
   */
  public multipleChange($event: any) {
    const { detail } = $event;
    if (!detail) {
      return;
    }
    const { value } = detail;
    const selections: any[] = [...this.c.selections];
    const selectItem = this.c.items.find((item: any) => {
      return Object.is(item.srfkey, value);
    });
    if (selectItem) {
      if (detail.checked) {
        selections.push(selectItem);
      } else {
        const index = selections.findIndex((i: any) => {
          return i.srfkey === selectItem.srfkey;
        });
        if (index != -1) {
          selections.splice(index, 1);
        }
      }
    }
    this.c.selectionChange(selections);
  }

  /**
   * @description 列表项左滑右滑触发行为
   * @param {*} $event 点击鼠标事件源
   * @param {*} detail 界面行为模型对象
   * @param {*} item 项数据
   * @memberof AppMobMDCtrl
   */
  public mdCtrlClick($event: any, detail: any, item: any): void {
    $event.stopPropagation();
    if (this.c.handleActionClick && this.c.handleActionClick instanceof Function) {
      this.c.handleActionClick(item, $event, detail);
    }
    this.closeSlidings(item);
  }

  /**
   * @description 关闭列表项左滑右滑
   * @param {*} item 项数据
   * @memberof AppMobMDCtrl
   */
  public closeSlidings(item: any) {
    const element = this.refsMap.get(item.srfkey)?.value;
    if (element && element.closeOpened && element.closeOpened instanceof Function) {
      element.closeOpened();
    }
  }

  /**
   * @description 渲染子项（布局面板）
   * @param {*} item 项数据
   * @return {*}
   * @memberof AppMobMDCtrl
   */
  public renderItemForLayoutPanel(item: any) {
    const _context = Util.deepCopy(this.c.context);
    Object.assign(_context, { [this.c.appDeCodeName.toLowerCase()]: item[this.c.appDeCodeName.toLowerCase()] });
    const otherParams = {
      navDatas: [item],
      navContext: _context,
      dataMap: this.c.dataMap,
    };
    return (
      <div style='width:100%;'>
        <ion-item class='item-layout'>
          {this.computeTargetCtrlData(this.c.controlInstance.getItemPSLayoutPanel() as IPSLayoutPanel, otherParams)}
        </ion-item>
      </div>
    );
  }

  /**
   * @description 渲染子项（默认内容）
   * @param {*} item 项数据
   * @param {*} index 索引
   * @return {*}
   * @memberof AppMobMDCtrl
   */
  public renderItemForDefault(item: any, index: any) {
    let valueFormat = '';
    const srfmajortext: IPSDEListDataItem | undefined = this.c.controlInstance
      .getPSDEListDataItems()
      ?.find((dataItem: IPSDEListDataItem) => Object.is('srfmajortext', dataItem.name));
    if (srfmajortext) {
      valueFormat = srfmajortext.format;
    }
    if (this.c.controlInstance.controlStyle == 'ICONVIEW') {
      return (
        <app-icon-item
          item={item}
          index={index}
          valueFormat={valueFormat}
          onClick={() => this.c.onRowSelect(item)}
        ></app-icon-item>
      );
    } else {
      return (
        <app-list-item
          item={item}
          index={index}
          valueFormat={valueFormat}
          onClick={() => this.c.onRowSelect(item)}
        ></app-list-item>
      );
    }
  }

  /**
   * @description 渲染多数据部件项
   * @param {*} item 项数据
   * @param {number} index 索引
   * @return {*}
   * @memberof AppMobMDCtrl
   */
  public renderMDCtrlItem(item: any, index: number) {
    if (this.c.controlInstance.controlStyle == 'ICONVIEW') {
      return (
        <div ref={this.refsMap.get(item.srfkey)} class='icon-item'>
          {this.c.controlInstance.getItemPSLayoutPanel()
            ? this.renderItemForLayoutPanel(item)
            : this.renderItemForDefault(item, index)}
        </div>
      );
    } else {
      return (
        <ion-item-sliding ref={this.refsMap.get(item.srfkey)} class='list-item' onIonDrag={this.ionDrag.bind(this)}>
          {this.renderListItemAction(item)}
          {this.c.controlInstance.getItemPSLayoutPanel()
            ? this.renderItemForLayoutPanel(item)
            : this.renderItemForDefault(item, index)}
        </ion-item-sliding>
      );
    }
  }

  /**
   * @description 渲染分组
   * @return {*}
   * @memberof AppMobMDCtrl
   */
  public renderHaveGroup() {
    if (this.c.controlInstance.controlStyle == 'ICONVIEW') {
      return (
        <div class='iconview-group'>
          {this.c.groupData.map((data: any) => {
            return (
              <div class='iconview-group-item'>
                <div class='group-title'>{data.text}</div>
                <div class='group-content'>
                  {data.items &&
                    data.items.length > 0 &&
                    data.items.map((item: any, index: number) => {
                      return this.renderMDCtrlItem(item, index);
                    })}
                </div>
              </div>
            );
          })}
        </div>
      );
    } else {
      return this.c.groupData.map((data: any) => {
        return (
          <div class='listview-group'>
            <ion-item-group>
              <ion-item-divider>
                <ion-label>{data.text}</ion-label>
              </ion-item-divider>
              {data.items &&
                data.items.length > 0 &&
                data.items.map((item: any, index: number) => {
                  return this.renderMDCtrlItem(item, index);
                })}
            </ion-item-group>
          </div>
        );
      });
    }
  }

  /**
   * @description 渲染无分组
   * @return {*}
   * @memberof AppMobMDCtrl
   */
  public renderNoGroup() {
    if (this.c.controlInstance.controlStyle == 'ICONVIEW') {
      return (
        <div class='iconview-nogroup'>
          {this.c.items.map((item: any, index: number) => {
            return this.renderMDCtrlItem(item, index);
          })}
        </div>
      );
    } else {
      return this.c.items.map((item: any, index: number) => {
        return this.renderMDCtrlItem(item, index);
      });
    }
  }

  /**
   * @description 绘制界面行为组
   * @param {*} item 项数据
   * @return {*}
   * @memberof AppMobMDCtrl
   */
  public renderListItemAction(item: any) {
    return [
      this.c.controlInstance?.getPSDEUIActionGroup?.() ? this.renderActionGroup(item) : null,
      this.c.controlInstance?.getPSDEUIActionGroup2?.() ? this.renderActionGroup2(item) : null,
    ];
  }

  /**
   * @description 绘制左滑界面行为组
   * @param {*} item 项数据
   * @return {*}
   * @memberof AppMobMDCtrl
   */
  public renderActionGroup(item: any) {
    //TODO 待补充国际化
    const details = this.c.controlInstance?.getPSDEUIActionGroup()?.getPSUIActionGroupDetails?.();
    if (this.c.controlInstance.controlStyle != 'LISTVIEW3') {
      return (
        <ion-item-options side='start'>
          {details &&
            details?.map((detail: IPSUIActionGroupDetail) => {
              const uiaction: IPSUIAction | null = detail.getPSUIAction();
              if (uiaction && item[uiaction.codeName]?.visabled) {
                const iconName = item[uiaction.codeName].icon ? ViewTool.setIcon(item[uiaction.codeName]?.icon) : '';
                return (
                  <ion-item-option
                    disabled={item[uiaction.codeName]?.disabled}
                    color={uiaction.uIActionTag == 'Remove' ? 'danger' : 'primary'}
                    onClick={($event: any) => this.mdCtrlClick($event, detail, item)}
                  >
                    {item[uiaction.codeName]?.icon && item[uiaction.codeName]?.isShowIcon && (
                      <app-icon name={iconName}></app-icon>
                    )}
                    {item[uiaction.codeName]?.isShowCaption && <ion-label>{uiaction.caption}</ion-label>}
                  </ion-item-option>
                );
              }
            })}
        </ion-item-options>
      );
    }
  }

  /**
   * @description 绘制右滑界面行为组
   * @param {*} item 项数据
   * @return {*}
   * @memberof AppMobMDCtrl
   */
  public renderActionGroup2(item: any) {
    //TODO 待补充国际化
    const details = this.c.controlInstance?.getPSDEUIActionGroup2()?.getPSUIActionGroupDetails?.();
    if (this.c.controlInstance.controlStyle != 'LISTVIEW3') {
      return (
        <ion-item-options side='end'>
          {details?.map((detail: IPSUIActionGroupDetail) => {
            const uiaction: IPSUIAction | null = detail.getPSUIAction();
            if (uiaction && item[uiaction.codeName]?.visabled) {
              const iconName = item[uiaction.codeName].icon ? ViewTool.setIcon(item[uiaction.codeName]?.icon) : '';
              return (
                <ion-item-option
                  disabled={item[uiaction.codeName]?.disabled}
                  color={uiaction.uIActionTag == 'Remove' ? 'danger' : 'primary'}
                  onClick={($event: any) => this.mdCtrlClick($event, detail, item)}
                >
                  {item[uiaction.codeName]?.icon && item[uiaction.codeName]?.isShowIcon && (
                    <app-icon name={iconName}></app-icon>
                  )}
                  {item[uiaction.codeName]?.isShowCaption && <ion-label>{uiaction.caption}</ion-label>}
                </ion-item-option>
              );
            }
          })}
        </ion-item-options>
      );
    }
  }

  /**
   * @description 渲染列表视图样式
   * @return {*}
   * @memberof AppMobMDCtrl
   */
  public renderMdctrlItemsListView() {
    return (
      <ion-list class='mdctrl-listview'>
        {Object.is('SELECT', this.c.ctrlShowMode)
          ? this.renderSelectMDCtrl()
          : this.c.isEnableGroup
          ? this.renderHaveGroup()
          : this.renderNoGroup()}
      </ion-list>
    );
  }

  /**
   * @description 渲染图标视图样式
   * @return {*}
   * @memberof AppMobMDCtrl
   */
  public renderMdctrlItemsIconView() {
    return <div class='mdctrl-iconview'>{this.c.isEnableGroup ? this.renderHaveGroup() : this.renderNoGroup()}</div>;
  }

  /**
   * @description 渲染多数据部件主体内容
   * @return {*}
   * @memberof AppMobMDCtrl
   */
  public renderMDCtrlContent() {
    if (this.c.items && this.c.items.length > 0) {
      this.initItemRef(this.c.items);
      if (this.c.controlInstance.controlStyle == 'ICONVIEW') {
        return this.renderMdctrlItemsIconView();
      } else {
        return this.renderMdctrlItemsListView();
      }
    }
  }

  /**
   * @description 绘制单多选
   * @return {*}
   * @memberof AppMobMDCtrl
   */
  public renderSelectMDCtrl() {
    if (!this.c.isMultiple) {
      return this.renderSimpleList();
    } else {
      return this.renderMultipleList();
    }
  }

  /**
   * @description 绘制单选列表
   * @return {*}
   * @memberof AppMobMDCtrl
   */
  public renderSimpleList() {
    const value = this.c.selections[0]?.srfkey;
    return (
      <ion-radio-group value={value} onIonChange={($event: any) => this.simpleChange($event)}>
        {this.c.items.map((item: any, index: number) => {
          return (
            <ion-item>
              <ion-radio value={item.srfkey}></ion-radio>
              <app-list-item item={item} index={index}></app-list-item>
            </ion-item>
          );
        })}
      </ion-radio-group>
    );
  }

  /**
   * @description 绘制多选列表
   * @return {*}
   * @memberof AppMobMDCtrl
   */
  public renderMultipleList() {
    return this.c.items.map((item: any, index: number) => {
      return (
        <ion-item>
          <ion-checkbox
            color='secondary'
            checked={item.checked}
            value={item.srfkey}
            onIonChange={($event: any) => this.multipleChange($event)}
          ></ion-checkbox>
          <app-list-item item={item} index={index}></app-list-item>
        </ion-item>
      );
    });
  }

  /**
   * @description 渲染触底加载更多
   * @return {*}
   * @memberof AppMobMDCtrl
   */
  public renderBottomRefresh() {
    return (
      <ion-infinite-scroll
        onIonInfinite={(event: any) => {
          this.loadMore(event);
        }}
        threshold='100px'
        disabled={this.loadMoreDisabled.value}
      >
        <ion-infinite-scroll-content
          loading-spinner='bubbles'
          loading-text={this.$tl('share.loading', '加载中···')}
        ></ion-infinite-scroll-content>
      </ion-infinite-scroll>
    );
  }

  /**
   * @description 绘制多数据部件
   * @return {*}
   * @memberof AppMobMDCtrl
   */
  render() {
    if (!this.controlIsLoaded.value) {
      return null;
    }
    const controlStyle = {
      width: this.c.controlInstance.width ? `${this.c.controlInstance.width}px` : '',
      height: this.c.controlInstance.height ? `${this.c.controlInstance.height}px` : '',
    };
    return this.c.items && this.c.items.length > 0 ? (
      <ion-content class={{ ...this.classNames }} style={controlStyle}>
        {[
          this.renderPullDownRefresh(),
          this.renderMDCtrlContent(),
          this.renderBottomRefresh(),
          this.renderBatchToolbar(),
        ]}
      </ion-content>
    ) : (
      [this.renderQuickToolbar(), this.renderNoData()]
    );
  }
}

export const AppMobMDCtrlComponent = GenerateComponent(AppMobMDCtrl, Object.keys(new AppMobMDCtrlProps()));
